﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;

using Extensibility;
using EnvDTE;
using EnvDTE80;
using VSC = Microsoft.VisualStudio.CommandBars;

namespace Antix.VSAddIn
{
    [Serializable()]
    public class CommandBars: IDTCommandTarget, IDisposable
    {
        #region Constructor

        internal CommandBars(Connect connect)
        {
            this._Connect = connect;
        }

        /// <summary>
        /// Destruct the object calling dispose
        /// </summary>
        ~CommandBars()
        {
            Dispose(false);
        }

        #endregion

        #region Properties

        private Connect _Connect;

        private VSC.CommandBar _Project;

        /// <summary>
        /// <para>Project Command Bar</para>
        /// </summary>
        public VSC.CommandBar Project
        {
            get
            {
                if (this._Project == null)
                {
                    this._Project = this.FindCommandBar(
                        new Guid("D309F791-903F-11D0-9EFC-00A0C911004F"),
                        1026);
                }

                return this._Project;
            }
        }

        private VSC.CommandBar _Item;

        /// <summary>
        /// <para>Item Command Bar</para>
        /// </summary>
        public VSC.CommandBar Item
        {
            get
            {
                if (this._Item == null)
                {
                    this._Item = ((VSC.CommandBars)_Connect.Application.CommandBars)["Item"];
                }

                return this._Item;
            }
        }

        #endregion

        #region Methods

        // Retrieves a specific CommandBar object, using a unique GUID:ID pair that identifies
        // the CommandBar.
        private VSC.CommandBar FindCommandBar(Guid guidCmdGroup, uint menuID)
        {
            // Make sure the CommandBars collection is properly initialized, before we attempt to
            // use the IVsProfferCommands service. The CommandBars collection is created on demand,
            // and we need to ensure it's actually available, before attemptign to retrieve the 
            // IVsProfferCommands interface.
            VSC.CommandBar menuBarCommandBar = ((VSC.CommandBars)_Connect.Application.CommandBars)["MenuBar"];

            //// Retrieve IVsProfferComands via DTE's IOleServiceProvider interface
            IVsProfferCommands commands = _Connect.GetService<IVsProfferCommands>();

            return ( VSC.CommandBar)commands.FindCommandBar(IntPtr.Zero, ref guidCmdGroup, menuID);
        }

        #endregion

        #region IDTCommandTarget Members

        public void Exec(string CmdName, vsCommandExecOption ExecuteOption, ref object VariantIn, ref object VariantOut, ref bool Handled)
        {
            throw new NotImplementedException();
        }

        public void QueryStatus(string CmdName, vsCommandStatusTextWanted NeededText, ref vsCommandStatus StatusOption, ref object CommandText)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IDisposable

        private bool _IsDisposed = false;

        /// <summary>
        /// Event raised on disposal of this object
        /// </summary>
        public event EventHandler Disposed;

        /// <summary>
        /// Dispose of this object
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!_IsDisposed)
            {
                if (disposing)
                {
                    // Dispose managed resources.
                    if (Disposed != null) { Disposed(this, new EventArgs()); }
                }
            }
            _IsDisposed = true;
        }

        /// <summary>
        /// Object is disposed or not
        /// </summary>
        public bool IsDisposed
        {
            get { return _IsDisposed; }
        }

        #endregion
    }
}